package com.ndood.db_doc;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.entity.Record;
import org.nutz.dao.impl.NutDao;
import org.nutz.dao.impl.SimpleDataSource;
import org.nutz.dao.sql.Sql;
import org.nutz.lang.Files;

import com.ndood.db_doc.pojo.ColumnVo;
import com.ndood.db_doc.pojo.TableVo;

/**
 * DatabaseDocService
 *
 * @author zt
 * @version 2018/10/6 0006
 */
public class DbDocGenerator {
    String sqlTables = "select table_name,table_comment from information_schema.tables where table_schema = '@dbname'" +
            " order by table_name asc";
    String sqlColumns = "select column_name,column_type,column_key,is_nullable,column_comment from information_schema" +
            ".columns where table_schema = '@dbname'  and table_name " +
            "='@tablename'";

    private Dao dao = null;
    public DbDocGenerator(Dao dao){
        this.dao = dao;
    }
    
    /**
     * 生成db doc
     */
    public void generateDoc(String dbName,String docPath){
        File docDir = new File(docPath);
        if(docDir.exists()){
            throw  new RuntimeException("该文件夹"+docPath+"已存在");
        }else{
            docDir.mkdirs();
        }
        String sql = sqlTables.replace("@dbname",dbName);
        List<Record> list = getList(sql);
        List<TableVo> tables = new ArrayList<>();
        for(int i=0;i<list.size();i++){
          Record record = list.get(i);
            String table = record.getString("table_name");
            String comment =record.getString("table_comment");
            TableVo tableVo = getTableInfo(table,comment,dbName);
            tables.add(tableVo);
        }
        makeDBDoc(tables,dbName,docPath);
    }
    
    /**
     * 生成一张表的bean模型
     */
    public TableVo getTableInfo(String table,String comment,String dbName){
        TableVo tableVo = new TableVo();
        tableVo.setTable(table);
        tableVo.setComment(comment);
        String sql = sqlColumns.replace("@dbname",dbName);
        sql = sql.replace("@tablename",table);
        List<Record> list =getList(sql);
        List<ColumnVo> columns = new ArrayList<>();
        for(int i=0;i<list.size();i++){
           Record record = list.get(i);
            ColumnVo column = new ColumnVo();
            column.setName(record.getString("column_name"));
            column.setType(record.getString("column_type"));
            column.setKey(record.getString("column_key"));
            column.setIsNullable(record.getString("is_nullable"));
            column.setComment(record.getString("column_comment"));
            columns.add(column);
        }
        tableVo.setColumns(columns);
        return tableVo;
    }

    public void makeDBDoc(List<TableVo> tables, String dbName, String docPath){
    	StringBuilder sb = new StringBuilder();
        for(TableVo table:tables){
        	StringBuilder builder =new StringBuilder("# "+table.getComment()+"("+table.getTable()+")").append("\r\n");
            builder.append("| 列名   | 类型   | KEY  | 是否为空 | 注释   |").append("\r\n");
            builder.append("| ---- | ---- | ---- | ---- | ---- |").append("\r\n");
            List<ColumnVo> columnVos = table.getColumns();
            for(int i=0;i<columnVos.size();i++){
                ColumnVo column = columnVos.get(i);
                builder.append("|").append(column.getName()).append("|").append(column.getType()).append("|").append
                        (column.getKey()).append("|").append(column.getIsNullable()).append("|").append(column.getComment
                        ()).append("|\r\n");
            }
            sb.append(builder.toString()).append("\r\n");
        }
        saveFile(sb.toString(),dbName,docPath);
    }

    private void saveFile(String docContent,String dbName, String docPath){
        try {
            Files.write(new File(docPath+File
                    .separator+"db.md"),docContent);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
    
    public List<Record> getList(String sqlStr){
        Sql sql = Sqls.create(sqlStr);
        sql.setCallback(Sqls.callback.records());
        dao.execute(sql);
        List<Record> list = sql.getList(Record.class);
        return list;
    }
    
    /**
     * https://gitee.com/enilu/database-doc-generator
     */
    @SuppressWarnings("resource")
	public static void main(String[] args) {
    	String ip = "121.196.208.113";
    	String port = "3306";
    	String dbName = "pay-boy-db";
    	String username = "root";

    	Scanner sc=new Scanner(System.in);
        System.out.println("input mysql password:");
        String passowrd = sc.nextLine();

        SimpleDataSource dataSource = new SimpleDataSource();
        dataSource.setJdbcUrl("jdbc:mysql://"+ip+":"+port+"/"+dbName);
        dataSource.setUsername(username);
        dataSource.setPassword(passowrd);
        Dao dao = new NutDao(dataSource);
        DbDocGenerator generator = new DbDocGenerator(dao);	
        generator.generateDoc(dbName,dbName+"-doc");
    }
}
